home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume5 / lwf / part02 < prev    next >
Encoding:
Internet Message Format  |  1989-02-03  |  50.5 KB

  1. Path: xanth!nic.MR.NET!hal!ncoast!allbery
  2. From: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  3. Newsgroups: comp.sources.misc
  4. Subject: v05i002: lwf (print Japanese on LW), part 2 of 3
  5. Message-ID: <8810201558.AA14577@uhccux.uhcc.Hawaii.Edu>
  6. Date: 22 Oct 88 02:35:28 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  9. Lines: 1989
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 5, Issue 2
  13. Submitted-by: "Greg Lee " <lee@uhccux.uhcc.Hawaii.Edu>
  14. Archive-name: lwf/Part2
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then unpack
  18. # it by saving it into a file and typing "sh file".  To overwrite existing
  19. # files, type "sh file -c".  You can also feed this as standard input via
  20. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  21. # will see the following message at the end:
  22. #        "End of archive 2 (of 3)."
  23. # Contents:  X.h lwf.c
  24. # Wrapped by lee@uhccux on Wed Oct 19 17:12:33 1988
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'X.h' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'X.h'\"
  28. else
  29. echo shar: Extracting \"'X.h'\" \(18246 characters\)
  30. sed "s/^X//" >'X.h' <<'END_OF_FILE'
  31. X/*
  32. X *    $Header: X.h,v 1.65 87/09/07 14:57:14 toddb Exp $
  33. X */
  34. X
  35. X/* Definitions for the X window system likely to be used by applications */
  36. X
  37. X#ifndef X_H
  38. X#define X_H
  39. X
  40. X/***********************************************************
  41. XCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  42. Xand the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  43. X
  44. X                        All Rights Reserved
  45. X
  46. XPermission to use, copy, modify, and distribute this software and its 
  47. Xdocumentation for any purpose and without fee is hereby granted, 
  48. Xprovided that the above copyright notice appear in all copies and that
  49. Xboth that copyright notice and this permission notice appear in 
  50. Xsupporting documentation, and that the names of Digital or MIT not be
  51. Xused in advertising or publicity pertaining to distribution of the
  52. Xsoftware without specific, written prior permission.  
  53. X
  54. XDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  55. XALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  56. XDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  57. XANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  58. XWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  59. XARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  60. XSOFTWARE.
  61. X
  62. X******************************************************************/
  63. X#define X_PROTOCOL    11        /* current protocol version */
  64. X#define X_PROTOCOL_REVISION 0        /* current minor version */
  65. X
  66. X/* Resources */
  67. X
  68. Xtypedef unsigned long XID;
  69. X
  70. Xtypedef XID Window;
  71. Xtypedef XID Drawable;
  72. Xtypedef XID Font;
  73. Xtypedef XID Pixmap;
  74. Xtypedef XID Cursor;
  75. Xtypedef XID Colormap;
  76. Xtypedef XID GContext;
  77. Xtypedef XID KeySym;
  78. X
  79. Xtypedef unsigned long Mask;
  80. X
  81. Xtypedef unsigned long Atom;
  82. X
  83. Xtypedef unsigned long VisualID;
  84. X
  85. Xtypedef unsigned long Time;
  86. X
  87. Xtypedef unsigned char KeyCode;
  88. X
  89. X/*****************************************************************
  90. X * RESERVED RESOURCE AND CONSTANT DEFINITIONS
  91. X *****************************************************************/
  92. X
  93. X#define None                 0L    /* universal null resource or null atom */
  94. X
  95. X#define ParentRelative       1L    /* background pixmap in CreateWindow
  96. X                    and ChangeWindowAttributes */
  97. X
  98. X#define CopyFromParent       0L    /* border pixmap in CreateWindow
  99. X                       and ChangeWindowAttributes
  100. X                   special VisualID and special window
  101. X                       class passed to CreateWindow */
  102. X
  103. X#define PointerWindow        0L    /* destination window in SendEvent */
  104. X#define InputFocus           1L    /* destination window in SendEvent */
  105. X
  106. X#define PointerRoot          1L    /* focus window in SetInputFocus */
  107. X
  108. X#define AnyPropertyType      0L    /* special Atom, passed to GetProperty */
  109. X
  110. X#define AnyKey             0L    /* special Key Code, passed to GrabKey */
  111. X
  112. X#define AnyButton            0L    /* special Button Code, passed to GrabButton */
  113. X
  114. X#define AllTemporary         0L    /* special Resource ID passed to KillClient */
  115. X
  116. X#define CurrentTime          0L    /* special Time */
  117. X
  118. X#define NoSymbol         0L    /* special KeySym */
  119. X
  120. X/***************************************************************** 
  121. X * EVENT DEFINITIONS 
  122. X *****************************************************************/
  123. X
  124. X/* Input Event Masks. Used as event-mask window attribute and as arguments
  125. X   to Grab requests.  Not to be confused with event names.  */
  126. X
  127. X#define NoEventMask            0L
  128. X#define KeyPressMask            (1L<<0)  
  129. X#define KeyReleaseMask            (1L<<1)  
  130. X#define ButtonPressMask            (1L<<2)  
  131. X#define ButtonReleaseMask        (1L<<3)  
  132. X#define EnterWindowMask            (1L<<4)  
  133. X#define LeaveWindowMask            (1L<<5)  
  134. X#define PointerMotionMask        (1L<<6)  
  135. X#define PointerMotionHintMask        (1L<<7)  
  136. X#define Button1MotionMask        (1L<<8)  
  137. X#define Button2MotionMask        (1L<<9)  
  138. X#define Button3MotionMask        (1L<<10) 
  139. X#define Button4MotionMask        (1L<<11) 
  140. X#define Button5MotionMask        (1L<<12) 
  141. X#define ButtonMotionMask        (1L<<13) 
  142. X#define KeymapStateMask            (1L<<14)
  143. X#define ExposureMask            (1L<<15) 
  144. X#define VisibilityChangeMask        (1L<<16) 
  145. X#define StructureNotifyMask        (1L<<17) 
  146. X#define ResizeRedirectMask        (1L<<18) 
  147. X#define SubstructureNotifyMask        (1L<<19) 
  148. X#define SubstructureRedirectMask    (1L<<20) 
  149. X#define FocusChangeMask            (1L<<21) 
  150. X#define PropertyChangeMask        (1L<<22) 
  151. X#define ColormapChangeMask        (1L<<23) 
  152. X#define OwnerGrabButtonMask        (1L<<24) 
  153. X
  154. X/* Event names.  Used in "type" field in XEvent structures.  Not to be
  155. Xconfused with event masks above.  They start from 2 because 0 and 1
  156. Xare reserved in the protocol for errors and replies. */
  157. X
  158. X#define KeyPress        2
  159. X#define KeyRelease        3
  160. X#define ButtonPress        4
  161. X#define ButtonRelease        5
  162. X#define MotionNotify        6
  163. X#define EnterNotify        7
  164. X#define LeaveNotify        8
  165. X#define FocusIn            9
  166. X#define FocusOut        10
  167. X#define KeymapNotify        11
  168. X#define Expose            12
  169. X#define GraphicsExpose        13
  170. X#define NoExpose        14
  171. X#define VisibilityNotify    15
  172. X#define CreateNotify        16
  173. X#define DestroyNotify        17
  174. X#define UnmapNotify        18
  175. X#define MapNotify        19
  176. X#define MapRequest        20
  177. X#define ReparentNotify        21
  178. X#define ConfigureNotify        22
  179. X#define ConfigureRequest    23
  180. X#define GravityNotify        24
  181. X#define ResizeRequest        25
  182. X#define CirculateNotify        26
  183. X#define CirculateRequest    27
  184. X#define PropertyNotify        28
  185. X#define SelectionClear        29
  186. X#define SelectionRequest    30
  187. X#define SelectionNotify        31
  188. X#define ColormapNotify        32
  189. X#define ClientMessage        33
  190. X#define MappingNotify        34
  191. X#define LASTEvent        35    /* must be bigger than any event # */
  192. X
  193. X
  194. X/* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer,
  195. X   state in various key-, mouse-, and button-related events. */
  196. X
  197. X#define ShiftMask        (1<<0)
  198. X#define LockMask        (1<<1)
  199. X#define ControlMask        (1<<2)
  200. X#define Mod1Mask        (1<<3)
  201. X#define Mod2Mask        (1<<4)
  202. X#define Mod3Mask        (1<<5)
  203. X#define Mod4Mask        (1<<6)
  204. X#define Mod5Mask        (1<<7)
  205. X
  206. X/* modifier names.  Used to build a SetModifierMapping request or
  207. X   to read a GetModifierMapping request.  These correspond to the
  208. X   masks defined above. */
  209. X#define ShiftMapIndex        0
  210. X#define LockMapIndex        1
  211. X#define ControlMapIndex        2
  212. X#define Mod1MapIndex        3
  213. X#define Mod2MapIndex        4
  214. X#define Mod3MapIndex        5
  215. X#define Mod4MapIndex        6
  216. X#define Mod5MapIndex        7
  217. X
  218. X
  219. X/* button masks.  Used in same manner as Key masks above. Not to be confused
  220. X   with button names below. */
  221. X
  222. X#define Button1Mask        (1<<8)
  223. X#define Button2Mask        (1<<9)
  224. X#define Button3Mask        (1<<10)
  225. X#define Button4Mask        (1<<11)
  226. X#define Button5Mask        (1<<12)
  227. X
  228. X#define AnyModifier        (1<<15)  /* used in GrabButton, GrabKey */
  229. X
  230. X
  231. X/* button names. Used as arguments to GrabButton and as detail in ButtonPress
  232. X   and ButtonRelease events.  Not to be confused with button masks above.
  233. X   Note that 0 is already defined above as "AnyButton".  */
  234. X
  235. X#define Button1            1
  236. X#define Button2            2
  237. X#define Button3            3
  238. X#define Button4            4
  239. X#define Button5            5
  240. X
  241. X/* Notify modes */
  242. X
  243. X#define NotifyNormal        0
  244. X#define NotifyGrab        1
  245. X#define NotifyUngrab        2
  246. X#define NotifyWhileGrabbed    3
  247. X
  248. X#define NotifyHint        1    /* for MotionNotify events */
  249. X               
  250. X/* Notify detail */
  251. X
  252. X#define NotifyAncestor        0
  253. X#define NotifyVirtual        1
  254. X#define NotifyInferior        2
  255. X#define NotifyNonlinear        3
  256. X#define NotifyNonlinearVirtual    4
  257. X#define NotifyPointer        5
  258. X#define NotifyPointerRoot    6
  259. X#define NotifyDetailNone    7
  260. X
  261. X/* Visibility notify */
  262. X
  263. X#define VisibilityUnobscured        0
  264. X#define VisibilityPartiallyObscured    1
  265. X#define VisibilityFullyObscured        2
  266. X
  267. X/* Circulation request */
  268. X
  269. X#define PlaceOnTop        0
  270. X#define PlaceOnBottom        1
  271. X
  272. X/* protocol families */
  273. X
  274. X#define FamilyInternet        0
  275. X#define FamilyDECnet        1
  276. X#define FamilyChaos        2
  277. X
  278. X/* Property notification */
  279. X
  280. X#define PropertyNewValue    0
  281. X#define PropertyDelete        1
  282. X
  283. X/* Color Map notification */
  284. X
  285. X#define ColormapUninstalled    0
  286. X#define ColormapInstalled    1
  287. X
  288. X/* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */
  289. X
  290. X#define GrabModeSync        0
  291. X#define GrabModeAsync        1
  292. X
  293. X/* GrabPointer, GrabKeyboard reply status */
  294. X
  295. X#define GrabSuccess        0
  296. X#define AlreadyGrabbed        1
  297. X#define GrabInvalidTime        2
  298. X#define GrabNotViewable        3
  299. X#define GrabFrozen        4
  300. X
  301. X/* AllowEvents modes */
  302. X
  303. X#define AsyncPointer        0
  304. X#define SyncPointer        1
  305. X#define ReplayPointer        2
  306. X#define AsyncKeyboard        3
  307. X#define SyncKeyboard        4
  308. X#define ReplayKeyboard        5
  309. X#define AsyncBoth        6
  310. X#define SyncBoth        7
  311. X
  312. X/* Used in SetInputFocus, GetInputFocus */
  313. X
  314. X#define RevertToNone        (int)None
  315. X#define RevertToPointerRoot    (int)PointerRoot
  316. X#define RevertToParent        2
  317. X
  318. X/*****************************************************************
  319. X * ERROR CODES 
  320. X *****************************************************************/
  321. X
  322. X#define Success           0    /* everything's okay */
  323. X#define BadRequest       1    /* bad request code */
  324. X#define BadValue       2    /* int parameter out of range */
  325. X#define BadWindow       3    /* parameter not a Window */
  326. X#define BadPixmap       4    /* parameter not a Pixmap */
  327. X#define BadAtom           5    /* parameter not an Atom */
  328. X#define BadCursor       6    /* parameter not a Cursor */
  329. X#define BadFont           7    /* parameter not a Font */
  330. X#define BadMatch       8    /* parameter mismatch */
  331. X#define BadDrawable       9    /* parameter not a Pixmap or Window */
  332. X#define BadAccess      10    /* depending on context:
  333. X                 - key/button already grabbed
  334. X                 - attempt to free an illegal 
  335. X                   cmap entry 
  336. X                - attempt to store into a read-only 
  337. X                   color map entry.
  338. X                 - attempt to modify the access control
  339. X                   list from other than the local host.
  340. X                */
  341. X#define BadAlloc      11    /* insufficient resources */
  342. X#define BadColor      12    /* no such colormap */
  343. X#define BadGC          13    /* parameter not a GC */
  344. X#define BadIDChoice      14    /* choice not in range or already used */
  345. X#define BadName          15    /* font or color name doesn't exist */
  346. X#define BadLength      16    /* Request length incorrect */
  347. X#define BadImplementation 17    /* server is defective */
  348. X
  349. X#define FirstExtensionError    128
  350. X#define LastExtensionError    255
  351. X
  352. X/*****************************************************************
  353. X * WINDOW DEFINITIONS 
  354. X *****************************************************************/
  355. X
  356. X/* Window classes used by CreateWindow */
  357. X/* Note that CopyFromParent is already defined as 0 above */
  358. X
  359. X#define InputOutput        1
  360. X#define InputOnly        2
  361. X
  362. X/* Window attributes for CreateWindow and ChangeWindowAttributes */
  363. X
  364. X#define CWBackPixmap        (1L<<0)
  365. X#define CWBackPixel        (1L<<1)
  366. X#define CWBorderPixmap        (1L<<2)
  367. X#define CWBorderPixel           (1L<<3)
  368. X#define CWBitGravity        (1L<<4)
  369. X#define CWWinGravity        (1L<<5)
  370. X#define CWBackingStore          (1L<<6)
  371. X#define CWBackingPlanes            (1L<<7)
  372. X#define CWBackingPixel            (1L<<8)
  373. X#define CWOverrideRedirect    (1L<<9)
  374. X#define CWSaveUnder        (1L<<10)
  375. X#define CWEventMask        (1L<<11)
  376. X#define CWDontPropagate            (1L<<12)
  377. X#define CWColormap        (1L<<13)
  378. X#define CWCursor            (1L<<14)
  379. X
  380. X/* ConfigureWindow structure */
  381. X
  382. X#define CWX            (1<<0)
  383. X#define CWY            (1<<1)
  384. X#define CWWidth            (1<<2)
  385. X#define CWHeight        (1<<3)
  386. X#define CWBorderWidth        (1<<4)
  387. X#define CWSibling        (1<<5)
  388. X#define CWStackMode        (1<<6)
  389. X
  390. X
  391. X/* Bit Gravity */
  392. X
  393. X#define ForgetGravity        0
  394. X#define NorthWestGravity    1
  395. X#define NorthGravity        2
  396. X#define NorthEastGravity    3
  397. X#define WestGravity        4
  398. X#define CenterGravity        5
  399. X#define EastGravity        6
  400. X#define SouthWestGravity    7
  401. X#define SouthGravity        8
  402. X#define SouthEastGravity    9
  403. X#define StaticGravity        10
  404. X
  405. X/* Window gravity + bit gravity above */
  406. X
  407. X#define UnmapGravity        0
  408. X
  409. X/* Used in CreateWindow for backing-store hint */
  410. X
  411. X#define NotUseful               0
  412. X#define WhenMapped              1
  413. X#define Always                  2
  414. X
  415. X/* Used in GetWindowAttributes reply */
  416. X
  417. X#define IsUnmapped        0
  418. X#define IsUnviewable        1
  419. X#define IsViewable        2
  420. X
  421. X/* Used in ChangeSaveSet */
  422. X
  423. X#define SetModeInsert           0
  424. X#define SetModeDelete           1
  425. X
  426. X/* Used in ChangeCloseDownMode */
  427. X
  428. X#define DestroyAll              0
  429. X#define RetainPermanent         1
  430. X#define RetainTemporary         2
  431. X
  432. X/* Window stacking method (in configureWindow) */
  433. X
  434. X#define Above                   0
  435. X#define Below                   1
  436. X#define TopIf                   2
  437. X#define BottomIf                3
  438. X#define Opposite                4
  439. X
  440. X/* Circulation direction */
  441. X
  442. X#define RaiseLowest             0
  443. X#define LowerHighest            1
  444. X
  445. X/* Property modes */
  446. X
  447. X#define PropModeReplace         0
  448. X#define PropModePrepend         1
  449. X#define PropModeAppend          2
  450. X
  451. X/*****************************************************************
  452. X * GRAPHICS DEFINITIONS
  453. X *****************************************************************/
  454. X
  455. X/* graphics functions, as in GC.alu */
  456. X
  457. X#define    GXclear            0x0        /* 0 */
  458. X#define GXand            0x1        /* src AND dst */
  459. X#define GXandReverse        0x2        /* src AND NOT dst */
  460. X#define GXcopy            0x3        /* src */
  461. X#define GXandInverted        0x4        /* NOT src AND dst */
  462. X#define    GXnoop            0x5        /* dst */
  463. X#define GXxor            0x6        /* src XOR dst */
  464. X#define GXor            0x7        /* src OR dst */
  465. X#define GXnor            0x8        /* NOT src AND NOT dst */
  466. X#define GXequiv            0x9        /* NOT src XOR dst */
  467. X#define GXinvert        0xa        /* NOT dst */
  468. X#define GXorReverse        0xb        /* src OR NOT dst */
  469. X#define GXcopyInverted        0xc        /* NOT src */
  470. X#define GXorInverted        0xd        /* NOT src OR dst */
  471. X#define GXnand            0xe        /* NOT src OR NOT dst */
  472. X#define GXset            0xf        /* 1 */
  473. X
  474. X/* LineStyle */
  475. X
  476. X#define LineSolid        0
  477. X#define LineOnOffDash        1
  478. X#define LineDoubleDash        2
  479. X
  480. X/* capStyle */
  481. X
  482. X#define CapNotLast        0
  483. X#define CapButt            1
  484. X#define CapRound        2
  485. X#define CapProjecting        3
  486. X
  487. X/* joinStyle */
  488. X
  489. X#define JoinMiter        0
  490. X#define JoinRound        1
  491. X#define JoinBevel        2
  492. X
  493. X/* fillStyle */
  494. X
  495. X#define FillSolid        0
  496. X#define FillTiled        1
  497. X#define FillStippled        2
  498. X#define FillOpaqueStippled    3
  499. X
  500. X/* fillRule */
  501. X
  502. X#define EvenOddRule        0
  503. X#define WindingRule        1
  504. X
  505. X/* subwindow mode */
  506. X
  507. X#define ClipByChildren        0
  508. X#define IncludeInferiors    1
  509. X
  510. X/* SetClipRectangles ordering */
  511. X
  512. X#define Unsorted        0
  513. X#define YSorted            1
  514. X#define YXSorted        2
  515. X#define YXBanded        3
  516. X
  517. X/* CoordinateMode for drawing routines */
  518. X
  519. X#define CoordModeOrigin        0    /* relative to the origin */
  520. X#define CoordModePrevious       1    /* relative to previous point */
  521. X
  522. X/* Polygon shapes */
  523. X
  524. X#define Complex            0    /* paths may intersect */
  525. X#define Nonconvex        1    /* no paths intersect, but not convex */
  526. X#define Convex            2    /* wholly convex */
  527. X
  528. X/* Arc modes for PolyFillArc */
  529. X
  530. X#define ArcChord        0    /* join endpoints of arc */
  531. X#define ArcPieSlice        1    /* join endpoints to center of arc */
  532. X
  533. X/* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into
  534. X   GC.stateChanges */
  535. X
  536. X#define GCFunction              (1L<<0)
  537. X#define GCPlaneMask             (1L<<1)
  538. X#define GCForeground            (1L<<2)
  539. X#define GCBackground            (1L<<3)
  540. X#define GCLineWidth             (1L<<4)
  541. X#define GCLineStyle             (1L<<5)
  542. X#define GCCapStyle              (1L<<6)
  543. X#define GCJoinStyle        (1L<<7)
  544. X#define GCFillStyle        (1L<<8)
  545. X#define GCFillRule        (1L<<9) 
  546. X#define GCTile            (1L<<10)
  547. X#define GCStipple        (1L<<11)
  548. X#define GCTileStipXOrigin    (1L<<12)
  549. X#define GCTileStipYOrigin    (1L<<13)
  550. X#define GCFont             (1L<<14)
  551. X#define GCSubwindowMode        (1L<<15)
  552. X#define GCGraphicsExposures     (1L<<16)
  553. X#define GCClipXOrigin        (1L<<17)
  554. X#define GCClipYOrigin        (1L<<18)
  555. X#define GCClipMask        (1L<<19)
  556. X#define GCDashOffset        (1L<<20)
  557. X#define GCDashList        (1L<<21)
  558. X#define GCArcMode        (1L<<22)
  559. X
  560. X#define GCLastBit        22
  561. X/*****************************************************************
  562. X * FONTS 
  563. X *****************************************************************/
  564. X
  565. X/* used in QueryFont -- draw direction */
  566. X
  567. X#define FontLeftToRight        0
  568. X#define FontRightToLeft        1
  569. X
  570. X#define FontChange        255
  571. X
  572. X/*****************************************************************
  573. X *  IMAGING 
  574. X *****************************************************************/
  575. X
  576. X/* ImageFormat -- PutImage, GetImage */
  577. X
  578. X#define XYBitmap        0    /* depth 1, XYFormat */
  579. X#define XYPixmap        1    /* depth == drawable depth */
  580. X#define ZPixmap            2    /* depth == drawable depth */
  581. X
  582. X/*****************************************************************
  583. X *  COLOR MAP STUFF 
  584. X *****************************************************************/
  585. X
  586. X/* For CreateColormap */
  587. X
  588. X#define AllocNone        0    /* create map with no entries */
  589. X#define AllocAll        1    /* allocate entire map writeable */
  590. X
  591. X
  592. X/* Flags used in StoreNamedColor, StoreColors */
  593. X
  594. X#define DoRed            (1<<0)
  595. X#define DoGreen            (1<<1)
  596. X#define DoBlue            (1<<2)
  597. X
  598. X/*****************************************************************
  599. X * CURSOR STUFF
  600. X *****************************************************************/
  601. X
  602. X/* QueryBestSize Class */
  603. X
  604. X#define CursorShape        0    /* largest size that can be displayed */
  605. X#define TileShape        1    /* size tiled fastest */
  606. X#define StippleShape        2    /* size stippled fastest */
  607. X
  608. X/***************************************************************** 
  609. X * KEYBOARD/POINTER STUFF
  610. X *****************************************************************/
  611. X
  612. X#define AutoRepeatModeOff    0
  613. X#define AutoRepeatModeOn    1
  614. X#define AutoRepeatModeDefault    2
  615. X
  616. X#define LedModeOff        0
  617. X#define LedModeOn        1
  618. X
  619. X/* masks for ChangeKeyboardControl */
  620. X
  621. X#define KBKeyClickPercent    (1L<<0)
  622. X#define KBBellPercent        (1L<<1)
  623. X#define KBBellPitch        (1L<<2)
  624. X#define KBBellDuration        (1L<<3)
  625. X#define KBLed            (1L<<4)
  626. X#define KBLedMode        (1L<<5)
  627. X#define KBKey            (1L<<6)
  628. X#define KBAutoRepeatMode    (1L<<7)
  629. X
  630. X#define MappingSuccess         0
  631. X#define MappingBusy            1
  632. X#define MappingFailed        2
  633. X
  634. X#define MappingModifier        0
  635. X#define MappingKeyboard        1
  636. X#define MappingPointer        2
  637. X
  638. X/*****************************************************************
  639. X * SCREEN SAVER STUFF 
  640. X *****************************************************************/
  641. X
  642. X#define DontPreferBlanking    0
  643. X#define PreferBlanking        1
  644. X#define DefaultBlanking        2
  645. X
  646. X#define DisableScreenSaver    0
  647. X#define DisableScreenInterval    0
  648. X
  649. X#define DontAllowExposures    0
  650. X#define AllowExposures        1
  651. X#define DefaultExposures    2
  652. X
  653. X/* for ForceScreenSaver */
  654. X
  655. X#define ScreenSaverReset 0
  656. X#define ScreenSaverActive 1
  657. X
  658. X/*****************************************************************
  659. X * HOSTS AND CONNECTIONS
  660. X *****************************************************************/
  661. X
  662. X/* for ChangeHosts */
  663. X
  664. X#define HostInsert        0
  665. X#define HostDelete        1
  666. X
  667. X/* for ChangeAccessControl */
  668. X
  669. X#define EnableAccess        1      
  670. X#define DisableAccess        0
  671. X
  672. X/* Display classes  used in opening the connection 
  673. X * Note that the statically allocated ones are even numbered and the
  674. X * dynamically changeable ones are odd numbered */
  675. X
  676. X#define StaticGray        0
  677. X#define GrayScale        1
  678. X#define StaticColor        2
  679. X#define PseudoColor        3
  680. X#define TrueColor        4
  681. X#define DirectColor        5
  682. X
  683. X
  684. X/* Byte order  used in imageByteOrder and bitmapBitOrder */
  685. X
  686. X#define LSBFirst        0
  687. X#define MSBFirst        1
  688. X
  689. X#endif /* X_H */
  690. END_OF_FILE
  691. if test 18246 -ne `wc -c <'X.h'`; then
  692.     echo shar: \"'X.h'\" unpacked with wrong size!
  693. fi
  694. # end of 'X.h'
  695. fi
  696. if test -f 'lwf.c' -a "${1}" != "-c" ; then 
  697.   echo shar: Will not clobber existing file \"'lwf.c'\"
  698. else
  699. echo shar: Extracting \"'lwf.c'\" \(29448 characters\)
  700. sed "s/^X//" >'lwf.c' <<'END_OF_FILE'
  701. X
  702. X/* vi: set tabstop=4 : */
  703. X
  704. X/*
  705. X * lwf - Convert ASCII text to PostScript
  706. X *
  707. X * Usage:
  708. X *    lwf [-d] [-i#] [-l] [-m] [-olist] [-p[str]] [-P filename] [-s#] [-t#]
  709. X *                [-v] [file ...]
  710. X *
  711. X * Options:
  712. X *    -d            Debug mode
  713. X *    -i#            Indent each line # inches (so much for metric)
  714. X *    -l            Landscape instead of Portrait
  715. X *    -m            Use 3 hole punch margins
  716. X *    -olist        Only print pages in the specified range
  717. X *    -p[str]        Use pr to print, passing optional string
  718. X *    -P filename Copy prologue from filename instead of default
  719. X *    -r            Toggle page reversal flag (see Makefile)
  720. X *    -s#            Use point size #
  721. X *    -t#            Spaces between tab stops is # characters
  722. X *    -v            Verbose
  723. X *    -S            Standalone mode (print header page, use EOF's)
  724. X *
  725. X * If no files are specified, stdin is used.
  726. X * Form feeds handled
  727. X * Backspacing with underlining (or overprinting) works
  728. X * The output conforms to Adobe 2.0
  729. X *
  730. X * Problems:
  731. X *    - assumes fixed-width (non-proportional) font in some places
  732. X *    - can't back up (using backspaces) over tabs
  733. X *    - assumes 8.5 x 11.0 paper
  734. X *
  735. X * BJB - Jun/87
  736. X * ========================================================================
  737. X *
  738. X * Permission is given to freely copy and distribute this software provided:
  739. X *
  740. X *    1) You do not sell it,
  741. X *    2) You do not use it for commercial advantage, and
  742. X *    3) This notice accompanies the distribution
  743. X *
  744. X * Copyright (c) 1988
  745. X * Barry Brachman
  746. X * Dept. of Computer Science
  747. X * Univ. of British Columbia
  748. X * Vancouver, B.C. V6T 1W5
  749. X *
  750. X * .. {ihnp4!alberta, uw-beaver, uunet}!ubc-vision!ubc-csgrads!brachman
  751. X * brachman@grads.cs.ubc.cdn
  752. X * brachman%ubc.csnet@csnet-relay.arpa
  753. X * brachman@ubc.csnet
  754. X * ========================================================================
  755. X */
  756. X
  757. X#include <sys/file.h>
  758. X#include <ctype.h>
  759. X#include <pwd.h>
  760. X#include <stdio.h>
  761. X
  762. X#define min(a, b)        ((a) < (b) ? (a) : (b))
  763. X
  764. X#define PROCPROL
  765. X/*
  766. X * Configurable...
  767. X * BUFOUT should be fairly large
  768. X */
  769. X#define BUFIN                1024    /* maximum length of an input line */
  770. X#define BUFOUT                (BUFIN * 5)
  771. X#define MAXPAGES            10000    /* maximum number of pages per job */
  772. X#define DEFAULT_TAB_SIZE    8
  773. X#define DEFAULT_POINT_SIZE    10
  774. X#ifndef PROLOGUE
  775. X#define PROLOGUE            "/usr/local/lib/lwf.prologue"
  776. X#endif
  777. X#ifdef KANJI
  778. X#ifndef KPLACE
  779. X#define KPLACE                "/usr/local/lib/k14.snf"
  780. X#endif
  781. X#endif
  782. X#ifndef REVERSE
  783. X#define REVERSE                0
  784. X#endif
  785. X#ifndef PR
  786. X#define PR                    "/bin/pr"
  787. X#endif
  788. X
  789. X#ifdef SYSV
  790. X#define rindex                strrchr
  791. X#endif
  792. X
  793. X/*
  794. X * As mentioned in the man page, /bin/pr doesn't handle formfeeds correctly
  795. X * when doing multicolumn formatting
  796. X * Instead of starting a new column or page it passes a formfeed through,
  797. X * causing pr and lwf to get out-of-synch with regard to the current
  798. X * location on the page
  799. X * If your pr behaves this way (4.[23] does, SYSV doesn't), define PRBUG so
  800. X * that fgetline() will filter out these bogus formfeeds while preserving
  801. X * the column structuring
  802. X */
  803. X#ifndef SYSV
  804. X#define PRBUG                1
  805. X#endif
  806. X
  807. X/*
  808. X * PostScript command strings defined in the prologue file
  809. X */
  810. X#define BACKSPACE        "B"
  811. X#define ENDPAGE            "EP"
  812. X#define LINETO            "L"
  813. X#define MOVETO            "M"
  814. X#define NEWPATH            "NP"
  815. X#define SHOW            "S"
  816. X#define STARTPAGE        "SP"
  817. X#define STARTHPAGE        "SHP"
  818. X#define STARTLPAGE        "SLP"
  819. X#define STROKE            "ST"
  820. X#define TAB                "T"
  821. X#ifdef KANJI
  822. X#define SHOWK            "K"
  823. X#endif
  824. X
  825. X/*
  826. X * Conformance requires that no PostScript line exceed 256 characters
  827. X */
  828. X#define MAX_OUTPUT_LINE_LENGTH    256
  829. X
  830. X#define TEXTFONT        "Courier"
  831. X#define HEADERFONT        "Times-Roman"
  832. X#define HEADERPS        18            /* header page point size */
  833. X
  834. X#define PORTRAIT_START_Y    768        /* first row (Y coord) on each page */
  835. X#define LANDSCAPE_START_Y    576
  836. X#define START_X                25        /* position of start of each line */
  837. X#define START_Y_HEADER        700        /* first row (Y coord) of header */
  838. X#define THREE_HOLE_X        1.0        /* portrait x offset (inches) 3 hole */
  839. X#define THREE_HOLE_Y        0.5        /* landscape y offset (inches) 3 hole */
  840. X
  841. X#define MAX_X            612
  842. X#define MAX_Y            792
  843. X
  844. X#define SEP_CHAR        '\001'        /* pr column separator character */
  845. X
  846. X#define PS_EOF            04
  847. X
  848. X#define NPSIZES            9
  849. Xstruct psize {
  850. X    int size;                        /* point size */
  851. X    double charsperinch;            /* approx. char width, for Courier */
  852. X    int portrait_page_length;        /* page length in lines */
  853. X    int portrait_cols;                /* maximum # of chars per line */
  854. X    int landscape_page_length;
  855. X    int landscape_cols;
  856. X} psize[NPSIZES] = {
  857. X     7, 17.0, 108, 135, 80, 181,
  858. X     8, 15.0,  94, 118, 70, 159,
  859. X     9, 14.0,  84, 105, 62, 141,
  860. X    10, 12.0,  75,  94, 56, 127,
  861. X    11, 11.0,  68,  86, 51, 115,
  862. X    12, 10.0,  62,  79, 46, 106,
  863. X    14,  8.8,  54,  67, 40,  90,
  864. X    16,  7.5,  47,  59, 35,  79,
  865. X    18,  7.0,  42,  52, 31,  70
  866. X};
  867. X
  868. X
  869. X#define USAGE    \
  870. X"[-d] [-i#] [-l] [-m] [-olist] [-p[str]] [-r] [-s#] [-t#] [-v] [-S] [file ...]"
  871. X
  872. Xlong page_map[MAXPAGES];    /* offset of first byte of each page */
  873. Xint page_count;
  874. X
  875. Xint lines_per_page;
  876. Xint columns;
  877. Xint point_size;
  878. Xint start_x, start_y;
  879. Xint ncopies;
  880. X
  881. Xchar bufin[BUFIN];            /* input buffer */
  882. Xchar bufout[BUFOUT];        /* used for page reversal and output buffering */
  883. X
  884. Xchar *currentdate, *username;
  885. Xchar hostname[32];
  886. X
  887. Xint row;
  888. Xchar *range;
  889. Xint tabstop;
  890. Xchar *propts;
  891. X
  892. Xint dflag, lflag, mflag, pflag, rflag, vflag, Sflag;
  893. X
  894. X#ifdef KANJI
  895. Xint kflag, kfontopen;
  896. Xextern char *kimage();
  897. Xextern int openkfont();
  898. Xextern void closekfont();
  899. X#endif
  900. X
  901. Xchar *strcpy();
  902. Xchar *fgetline();
  903. Xchar *sprintf();
  904. X
  905. Xchar *prologue;
  906. Xchar *progname;
  907. X
  908. Xchar *version = "lwf V2.0 brachman@ubc.csnet 21-Feb-88";
  909. X
  910. Xmain(argc, argv)
  911. Xint argc;
  912. Xchar **argv;
  913. X{
  914. X    register int i, j, first_file;
  915. X    char *pc;
  916. X    struct psize *p, *get_psize();
  917. X    double offset, atof();
  918. X    char *rindex();
  919. X    FILE *infile, *popen();
  920. X    double ceil();
  921. X
  922. X    if ((pc = rindex(argv[0], '/')) != (char *) NULL)
  923. X        progname = pc + 1;
  924. X    else
  925. X        progname = argv[0];
  926. X    range = ":";
  927. X    propts = "";
  928. X    tabstop = DEFAULT_TAB_SIZE;
  929. X    page_count = 0;
  930. X    ncopies = 1;
  931. X    offset = 0.0;
  932. X    prologue = PROLOGUE;
  933. X    p = get_psize(DEFAULT_POINT_SIZE);
  934. X    rflag = REVERSE;
  935. X
  936. X    for (i = 1; i < argc && argv[i][0] == '-'; i++) {
  937. X        switch (argv[i][1]) {
  938. X        case 'c':
  939. X            ncopies = atof(&argv[i][2]);
  940. X            if (ncopies <= 0) {
  941. X                fatal("number of copies must be > 0");
  942. X                /*NOTREACHED*/
  943. X            }
  944. X            break;
  945. X        case 'd':
  946. X            dflag = 1;
  947. X            break;
  948. X        case 'i':
  949. X            offset = atof(&argv[i][2]);
  950. X            if (offset < 0.0 || offset >= 8.5) {
  951. X                fatal("bad indent");
  952. X                /*NOTREACHED*/
  953. X            }
  954. X            break;
  955. X        case 'l':
  956. X            lflag = 1;
  957. X            break;
  958. X        case 'm':
  959. X            mflag = 1;
  960. X            break;
  961. X        case 'o':
  962. X            range = &argv[i][2];
  963. X            if (checkrange(range)) {
  964. X                fatal("bad range specification");
  965. X                /*NOTREACHED*/
  966. X            }
  967. X            break;
  968. X        case 'p':
  969. X            pflag = 1;
  970. X            propts = &argv[i][2];
  971. X            break;
  972. X        case 'P':
  973. X            if (++i == argc) {
  974. X                fatal("missing filename after -P");
  975. X                /*NOTREACHED*/
  976. X            }
  977. X            prologue = argv[i];
  978. X            break;
  979. X        case 'r':
  980. X            rflag = !rflag;
  981. X            break;
  982. X        case 's':
  983. X            j = atoi(&argv[i][2]);
  984. X            if ((p = get_psize(j)) == (struct psize *) NULL) {
  985. X                fatal("bad point size");
  986. X                /*NOTREACHED*/
  987. X            }
  988. X            break;
  989. X        case 't':
  990. X            tabstop = atoi(&argv[i][2]);
  991. X            if (tabstop < 1) {
  992. X                fatal("bad tabstop");
  993. X                /*NOTREACHED*/
  994. X            }
  995. X            break;
  996. X        case 'v':
  997. X            vflag = 1;
  998. X            break;
  999. X        case 'S':
  1000. X            Sflag = 1;
  1001. X            break;
  1002. X        default:
  1003. X            (void) fprintf(stderr, "Usage: %s %s\n", progname, USAGE);
  1004. X            exit(1);
  1005. X        }
  1006. X    }
  1007. X
  1008. X    /*
  1009. X     * Check that all files are readable
  1010. X     * This is so that no output at all is produced if any file is not
  1011. X     * readable in case the output is being piped to a printer
  1012. X     */
  1013. X    for (j = i; j < argc; j++) {
  1014. X        if (access(argv[j], R_OK) == -1) {
  1015. X            fatal("cannot access %s", argv[j]);
  1016. X            /*NOTREACHED*/
  1017. X        }
  1018. X    }
  1019. X
  1020. X    point_size = p->size;
  1021. X
  1022. X    if (lflag) {
  1023. X        start_y = LANDSCAPE_START_Y;
  1024. X        start_x = START_X + (int) (offset * 72.27);
  1025. X        lines_per_page = p->landscape_page_length;
  1026. X        columns = p->landscape_cols - (int) ceil(offset * p->charsperinch);
  1027. X        if (mflag) {
  1028. X            int nlines;
  1029. X
  1030. X            nlines = (int) ceil((THREE_HOLE_Y * 72.27) / point_size);
  1031. X            start_y -= (nlines * point_size);
  1032. X            lines_per_page -= nlines;
  1033. X            columns -= (int) ceil(THREE_HOLE_Y * p->charsperinch);
  1034. X        }
  1035. X    }
  1036. X    else {
  1037. X        start_y = PORTRAIT_START_Y;
  1038. X        lines_per_page = p->portrait_page_length;
  1039. X        start_x = START_X;
  1040. X        if (mflag)
  1041. X                offset += THREE_HOLE_X;
  1042. X        start_x += (int) (offset * 72.27);
  1043. X        columns = p->portrait_cols - (int) ceil(offset * p->charsperinch);
  1044. X    }
  1045. X    if (vflag) {
  1046. X        (void) fprintf(stderr, "%s\n\n", version);
  1047. X        (void) fprintf(stderr, "Lines/page = %d\n", lines_per_page);
  1048. X        (void) fprintf(stderr, "Columns = %d\n", columns);
  1049. X        (void) fprintf(stderr, "X-offset = %5.2f inches\n", offset);
  1050. X    }
  1051. X
  1052. X    setup();
  1053. X    preamble();
  1054. X
  1055. X    first_file = i;
  1056. X
  1057. X    if (!rflag && Sflag)
  1058. X        header(argc - first_file, argv + first_file);
  1059. X
  1060. X    if (i == argc) {    /* no files on command line */
  1061. X        infile = stdin;
  1062. X        if (pflag) {
  1063. X            build_prcmd(bufin, "");
  1064. X            if ((infile = popen(bufin, "r")) == (FILE *) NULL) {
  1065. X                fatal("popen failed");
  1066. X                /*NOTREACHED*/
  1067. X            }
  1068. X        }
  1069. X        if (vflag)
  1070. X            (void) fprintf(stderr, "printing stdin\n");
  1071. X        print(infile);
  1072. X        if (pflag)
  1073. X            (void) pclose(infile);
  1074. X    }
  1075. X
  1076. X    /*
  1077. X     * If page reversal is performed, process the file arguments right to left,
  1078. X     * oth. left to right
  1079. X     * If the correct flag is used for the printer the first file argument
  1080. X     * will be on top in the printer's output tray when the paper is removed
  1081. X     */
  1082. X    if (rflag)
  1083. X        j = argc - 1;
  1084. X    else
  1085. X        j = i;
  1086. X    while (i < argc) {
  1087. X        infile = stdin;
  1088. X        if (pflag) {
  1089. X            build_prcmd(bufin, argv[j]);
  1090. X            if ((infile = popen(bufin, "r")) == (FILE *) NULL) {
  1091. X                fatal("popen failed");
  1092. X                /*NOTREACHED*/
  1093. X            }
  1094. X        }
  1095. X        else {
  1096. X            if (freopen(argv[j], "r", stdin) == (FILE *) NULL) {
  1097. X                fatal("can't open %s", argv[j]);
  1098. X                /*NOTREACHED*/
  1099. X            }
  1100. X        }
  1101. X        if (vflag)
  1102. X            (void) fprintf(stderr, "printing %s\n", argv[j]);
  1103. X        print(infile);
  1104. X        if (pflag)
  1105. X            (void) pclose(infile);
  1106. X        if (rflag)
  1107. X            j--;
  1108. X        else
  1109. X            j++;
  1110. X        i++;
  1111. X    }
  1112. X
  1113. X    if (rflag && Sflag)
  1114. X        header(argc - first_file, argv + first_file);
  1115. X
  1116. X    (void) printf("%%%%Trailer\n");
  1117. X    (void) printf("%%%%Pages: %d\n", page_count);
  1118. X    if (Sflag)
  1119. X        (void) putc(PS_EOF, stdout);
  1120. X
  1121. X    if (fflush(stdout) == EOF) {
  1122. X        fatal("write error on stdout");
  1123. X        /*NOTREACHED*/
  1124. X    }
  1125. X#ifdef KANJI
  1126. X    if (kfontopen) closekfont();
  1127. X#endif
  1128. X    exit(0);
  1129. X}
  1130. X
  1131. X/*
  1132. X * Return a pointer to the point size structure for the
  1133. X * specified point size
  1134. X */
  1135. Xstruct psize *
  1136. Xget_psize(size)
  1137. Xint size;
  1138. X{
  1139. X    register int i;
  1140. X
  1141. X    for (i = 0; i < NPSIZES; i++)
  1142. X        if (psize[i].size == size)
  1143. X            break;
  1144. X    if (i == NPSIZES)
  1145. X        return((struct psize *) NULL);
  1146. X    return(&psize[i]);
  1147. X}
  1148. X
  1149. X/*
  1150. X * Initial lines sent to the LaserWriter
  1151. X * This stuff is sent to stdout since we don't want it to be reversed
  1152. X * Generates the PostScript header and includes the prologue file
  1153. X * There is limited checking for I/O errors here
  1154. X * When the standard prologue is being used we probably should verify
  1155. X * that it is the correct version (via %%BeginProcSet)
  1156. X */
  1157. Xpreamble()
  1158. X{
  1159. X#ifndef PROCPROL
  1160. X    FILE *fp;
  1161. X
  1162. X    if ((fp = fopen(prologue, "r")) == (FILE *) NULL) {
  1163. X        fatal("can't open prologue file `%s'", prologue);
  1164. X        /*NOTREACHED*/
  1165. X    }
  1166. X#endif
  1167. X    if (Sflag)
  1168. X        (void) putc(PS_EOF, stdout);
  1169. X
  1170. X    (void) printf("%%!PS-Adobe-2.0\n");
  1171. X    (void) printf("%%%%Creator: %s on %s\n", progname, hostname);
  1172. X    (void) printf("%%%%CreationDate: %s\n", currentdate);
  1173. X    (void) printf("%%%%For: %s\n", username);
  1174. X    (void) printf("%%%%DocumentFonts: %s", TEXTFONT);
  1175. X    if (Sflag)
  1176. X        (void) printf(" %s\n", HEADERFONT);
  1177. X    else
  1178. X        (void) printf("\n");
  1179. X    (void) printf("%%%%Pages: (atend)\n");
  1180. X#ifndef PROCPROL
  1181. X    while (fgets(bufin, sizeof(bufin), fp) != (char *) NULL)
  1182. X        fputs(bufin, stdout);
  1183. X    (void) fclose(fp);
  1184. X#else
  1185. X    doprologue();
  1186. X#endif
  1187. X
  1188. X    if (ferror(stdout) || fflush(stdout) == EOF) {
  1189. X        fatal("write error on stdout");
  1190. X        /*NOTREACHED*/
  1191. X    }
  1192. X}
  1193. X#ifdef PROCPROL
  1194. X
  1195. Xdoprologue()
  1196. X{
  1197. X    printf("%%%%EndComments\n");
  1198. X    printf("%% PostScript Prologue for lwf V2.0 ASCII to PostScript filter\n");
  1199. X    printf("%% Barry Brachman\n");
  1200. X    printf("%% Dept. of Computer Science\n");
  1201. X    printf("%% University of British Columbia\n");
  1202. X    printf("/B {NW 0 rmoveto}bind def\n");
  1203. X    printf("/EP {SV restore /#copies exch def showpage}bind def\n");
  1204. X    printf("/L /lineto load def\n");
  1205. X    printf("/M /moveto load def\n");
  1206. X    printf("/NP /newpath load def\n");
  1207. X    printf("/S /show load def\n");
  1208. X    printf("/SHP {SP 2 setlinewidth}bind def\n");
  1209. X    printf("/SLP {SP 612 0 translate 90 rotate}bind def\n");
  1210. X    printf("/SP {/SV save def findfont exch scalefont setfont ( )\n");
  1211. X    printf("  stringwidth pop dup /W exch def neg /NW exch def}bind def\n");
  1212. X    printf("/ST /stroke load def\n");
  1213. X    printf("/T {W mul 0 rmoveto}bind def\n");
  1214. X    printf("/K {/kimage exch def gsave currentpoint translate W W scale\n");
  1215. X    printf(" 14 14 true [14 0 0 -14 0 14] kimage imagemask\n");
  1216. X    printf(" grestore W 0 rmoveto}bind def\n");
  1217. X    printf("%%%%EndProlog\n");
  1218. X}
  1219. X#endif
  1220. X
  1221. X/*
  1222. X * Generate a command, in the specified buffer, to print the given file
  1223. X * according to the options in effect
  1224. X */
  1225. Xbuild_prcmd(buf, file)
  1226. Xchar *buf, *file;
  1227. X{
  1228. X
  1229. X#ifdef SYSV
  1230. X    (void) sprintf(buf, "%s -e%d -w%d -l%d -s%c %s %s",
  1231. X                PR, tabstop, columns, lines_per_page, SEP_CHAR, propts, file);
  1232. X#else
  1233. X    (void) sprintf(buf, "%s -w%d -l%d -s%c %s %s",
  1234. X                        PR, columns, lines_per_page, SEP_CHAR, propts, file);
  1235. X#endif
  1236. X    if (vflag)
  1237. X        (void) fprintf(stderr, "pr cmd: %s\n", buf);
  1238. X}
  1239. X
  1240. X/*
  1241. X * Print a file
  1242. X *
  1243. X * The input stream may be stdin, a file, or a pipe
  1244. X * If page reversal is being performed, the output goes to a temporary file and
  1245. X * then reverse() is called to do the page reversal to stdout
  1246. X */
  1247. Xprint(infile)
  1248. XFILE *infile;
  1249. X{
  1250. X    register int eof, pagenum, r;
  1251. X    register char *p;
  1252. X    FILE *outfile;
  1253. X    char *mktemp();
  1254. X
  1255. X    if (rflag) {
  1256. X        static char bigbuf[BUFOUT];
  1257. X
  1258. X        page_map[0] = 0L;
  1259. X        (void) sprintf(bufin, "/tmp/%sXXXXXX", progname);
  1260. X        if (vflag)
  1261. X            (void) fprintf(stderr, "temp will be: %s ... ", bufin);
  1262. X        p = mktemp(bufin);
  1263. X        if (vflag)
  1264. X            (void) fprintf(stderr, "%s\n", p);
  1265. X        if ((outfile = fopen(p, "w+")) == (FILE *) NULL) {
  1266. X            (void) fprintf(stderr, "%s: can't create %s\n", progname, p);
  1267. X            cleanup();
  1268. X            /*NOTREACHED*/
  1269. X        }
  1270. X        setbuffer(outfile, bigbuf, sizeof(bigbuf));
  1271. X        if (!dflag)
  1272. X            (void) unlink(p);
  1273. X        else
  1274. X            (void) fprintf(stderr, "will not unlink %s\n", p);
  1275. X    }
  1276. X    else
  1277. X        outfile = stdout;
  1278. X
  1279. X    pagenum = 1;
  1280. X    eof = 0;
  1281. X    while (!eof) {
  1282. X        row = start_y;
  1283. X        if ((r = inrange(pagenum, range)) == -1) {
  1284. X            cleanup();
  1285. X            /*NOTREACHED*/
  1286. X        }
  1287. X        else if (r == 1)
  1288. X            eof = printpage(infile, outfile);
  1289. X        else if (r == 0)
  1290. X            eof = flushpage(infile);
  1291. X        else {
  1292. X            fatal("bad inrange result");
  1293. X            /*NOTREACHED*/
  1294. X        }
  1295. X        pagenum++;
  1296. X    }
  1297. X    if (row != start_y)
  1298. X        endpage(outfile);
  1299. X    if (vflag)
  1300. X        (void) fprintf(stderr, "\n");
  1301. X    if (fflush(outfile) == EOF) {
  1302. X        fatal("write error while flushing output");
  1303. X        /*NOTREACHED*/
  1304. X    }
  1305. X    if (rflag) {
  1306. X        reverse(outfile);
  1307. X        (void) fclose(outfile);
  1308. X    }
  1309. X}
  1310. X
  1311. X/*
  1312. X * Process the next page
  1313. X * Return 1 on EOF, 0 oth.
  1314. X */
  1315. Xprintpage(infile, outfile)
  1316. XFILE *infile, *outfile;
  1317. X{
  1318. X    register int lineno;
  1319. X
  1320. X    if (ungetc(getc(infile), infile) == EOF)
  1321. X        return(1);
  1322. X
  1323. X    startpage(page_count + 1, outfile);
  1324. X    for (lineno = 0; lineno < lines_per_page; lineno++) {
  1325. X        if (fgetline(bufin, sizeof(bufin), infile) == (char *) NULL)
  1326. X            return(1);
  1327. X        if (bufin[0] == '\f')
  1328. X            break;
  1329. X        if (bufin[0] != '\0') {
  1330. X            (void) fprintf(outfile, "%d %d %s\n", start_x, row, MOVETO);
  1331. X            proc(bufin, outfile);
  1332. X        }
  1333. X        row -= point_size;
  1334. X    }
  1335. X    endpage(outfile);
  1336. X    return(0);
  1337. X}
  1338. X
  1339. X/*
  1340. X * The next page will not be printed; just consume the input and discard
  1341. X * Don't change xrow since we don't want an endpage()
  1342. X */
  1343. Xflushpage(infile)
  1344. XFILE *infile;
  1345. X{
  1346. X    register int lineno, xrow;
  1347. X
  1348. X    xrow = row;
  1349. X    for (lineno = 0; lineno < lines_per_page; lineno++) {
  1350. X        if (fgetline(bufin, sizeof(bufin), infile) == (char *) NULL)
  1351. X            return(1);
  1352. X        if (bufin[0] == '\f')
  1353. X            break;
  1354. X        xrow -= point_size;
  1355. X    }
  1356. X    return(0);
  1357. X}
  1358. X
  1359. X/*
  1360. X * Start a new page
  1361. X */
  1362. Xstartpage(n, outfile)
  1363. Xint n;
  1364. XFILE *outfile;
  1365. X{
  1366. X
  1367. X    (void) fprintf(outfile, "%%%%Page: ? %d\n", n);
  1368. X    (void) fprintf(outfile, "%d /%s %s\n",
  1369. X            point_size, TEXTFONT, lflag ? STARTLPAGE : STARTPAGE);
  1370. X}
  1371. X
  1372. X/*
  1373. X * A page has been written to the temp file
  1374. X * Record the start of the next page
  1375. X * Terminate the page and indicate the start of the next
  1376. X */
  1377. Xendpage(outfile)
  1378. XFILE *outfile;
  1379. X{
  1380. X    long ftell();
  1381. X
  1382. X    if (page_count == MAXPAGES) {
  1383. X        fatal("pagelimit (%d) reached", MAXPAGES);
  1384. X        /*NOTREACHED*/
  1385. X    }
  1386. X    (void) fprintf(outfile, "%d %s\n", ncopies, ENDPAGE);
  1387. X    if (rflag) {
  1388. X        if (fflush(outfile) == EOF) {
  1389. X            fatal("write error while flushing page");
  1390. X            /*NOTREACHED*/
  1391. X        }
  1392. X        page_map[++page_count] = ftell(outfile);
  1393. X    }
  1394. X    else
  1395. X        page_count++;
  1396. X    if (vflag)
  1397. X        (void) fprintf(stderr, "x");
  1398. X}
  1399. X
  1400. X/*
  1401. X * Print the pages to stdout in reverse order
  1402. X * Assumes that the number of characters per page can be contained in an int
  1403. X */
  1404. Xreverse(outfile)
  1405. XFILE *outfile;
  1406. X{
  1407. X    register int i;
  1408. X    int bytecount, nbytes;
  1409. X    long lseek();
  1410. X
  1411. X    if (vflag)
  1412. X        (void) fprintf(stderr, "\nreversing %d page%s\n", page_count,
  1413. X                        page_count > 1 ? "s" : "");
  1414. X    if (dflag) {
  1415. X        for (i = 0; i <= page_count; i++)
  1416. X            (void) fprintf(stderr, "[%ld]\n", page_map[i]);
  1417. X    }
  1418. X    for (i = page_count - 1; i >= 0; i--) {
  1419. X        if (fseek(outfile, page_map[i], 0) == -1L) {
  1420. X            fatal("seek error");
  1421. X            /*NOTREACHED*/
  1422. X        }
  1423. X        nbytes = (int) (page_map[i + 1] - page_map[i]);
  1424. X        while (nbytes > 0) {
  1425. X            bytecount = min(nbytes, sizeof(bufout));
  1426. X            if (fread(bufout, 1, bytecount, outfile) != bytecount) {
  1427. X                fatal("read error while reversing pages");
  1428. X                /*NOTREACHED*/
  1429. X            }
  1430. X            if (fwrite(bufout, 1, bytecount, stdout) != bytecount) {
  1431. X                fatal("write error while reversing pages");
  1432. X                /*NOTREACHED*/
  1433. X            }
  1434. X            nbytes -= bytecount;
  1435. X        }
  1436. X    }
  1437. X}
  1438. X
  1439. X/*
  1440. X * Process a line of input, escaping characters when necessary and handling
  1441. X * tabs
  1442. X *
  1443. X * The output is improved somewhat by coalescing consecutive tabs and
  1444. X * backspaces and eliminating tabs at the end of a line
  1445. X *
  1446. X * Overprinting (presumably most often used in underlining) can be far from
  1447. X * optimal; in particular the way nroff underlines by sequences like
  1448. X * "_\ba_\bb_\bc" creates a large volume of PostScript.  This isn't too
  1449. X * serious since a lot of nroff underlining is unlikely.
  1450. X *
  1451. X * Since a newline is generated for each call there will be more
  1452. X * newlines in the output than is necessary
  1453. X */
  1454. Xproc(in, outfile)
  1455. Xchar *in;
  1456. XFILE *outfile;
  1457. X{
  1458. X    register int i;
  1459. X    register char *last, *p, *q;
  1460. X    int currentp, instr, tabc, tabto;
  1461. X    char *savep;
  1462. X    static int colskip, ncols;
  1463. X    static int seen_sep = 0;
  1464. X
  1465. X    currentp = 0;
  1466. X    instr = 0;
  1467. X    tabto = 0;
  1468. X    last = bufout + MAX_OUTPUT_LINE_LENGTH - 20;    /* subtract slop factor */
  1469. X
  1470. X    q = bufout;
  1471. X    *q = '\0';
  1472. X    for (p = in; *p != '\0'; p++) {
  1473. X        switch (*p) {
  1474. X        case SEP_CHAR:
  1475. X            /*
  1476. X             * This assumes that the input buffer contains the entire line
  1477. X             * oth. the column count will be off
  1478. X             * Also, the input stream must be formatted into a constant number
  1479. X             * of columns oth. it would be necessary to scan each line to
  1480. X             * count SEP_CHARs (which is not hard but could be slow)
  1481. X             */
  1482. X            if (!seen_sep) {            /* discern number of columns */
  1483. X                seen_sep = 1;
  1484. X                ncols = 2;                /* there are at least two columns... */
  1485. X                savep = p++;
  1486. X                while (*p != '\0') {
  1487. X                    if (*p++ == SEP_CHAR)
  1488. X                        ncols++;
  1489. X                }
  1490. X                p = savep;
  1491. X                colskip = columns / ncols;
  1492. X                if (vflag)
  1493. X                    (void) fprintf(stderr, "Using %d columns\n", ncols);
  1494. X            }
  1495. X            if (instr) {
  1496. X                (void) sprintf(q, ")%s ", SHOW);
  1497. X                q += strlen(q);
  1498. X                instr = 0;
  1499. X            }
  1500. X            tabto += (colskip - currentp);
  1501. X            currentp = 0;
  1502. X            break;
  1503. X        case '\t':
  1504. X            /*
  1505. X             * Count the number of tabs that immediately follow the one we're
  1506. X             * looking at
  1507. X             */
  1508. X            tabc = 0;
  1509. X            while (*(p + 1) == '\t') {
  1510. X                p++;
  1511. X                tabc++;
  1512. X            }
  1513. X            if (currentp > 0) {        /* not beginning of line */
  1514. X                i = tabstop - (currentp % tabstop) + tabc * tabstop;
  1515. X                if (instr) {
  1516. X                    (void) sprintf(q, ")%s ", SHOW);
  1517. X                    q += strlen(q);
  1518. X                    instr = 0;
  1519. X                }
  1520. X            }
  1521. X            else
  1522. X                i = (tabc + 1) * tabstop;
  1523. X            tabto += i;
  1524. X            currentp += i;
  1525. X            break;
  1526. X        case '\b':
  1527. X            *q = '\0';
  1528. X            (void) fprintf(outfile, "%s)%s\n", bufout, SHOW);
  1529. X            /* backspacing over tabs doesn't work... */
  1530. X            if (tabto != 0) {
  1531. X                fatal("attempt to backspace over a tab");
  1532. X                /*NOTREACHED*/
  1533. X            }
  1534. X            p++;
  1535. X            for (i = 1; *p == '\b'; p++)
  1536. X                i++;
  1537. X            if (currentp - i < 0) {
  1538. X                fatal("too many backspaces");
  1539. X                /*NOTREACHED*/
  1540. X            }
  1541. X            if (!instr) {
  1542. X                fatal("bad backspacing");
  1543. X                /*NOTREACHED*/
  1544. X            }
  1545. X            if (i == 1)                /* frequent case gets special attention */
  1546. X                (void) sprintf(bufout, "%s (", BACKSPACE);
  1547. X            else
  1548. X                (void) sprintf(bufout, "-%d %s (", i, TAB);
  1549. X            currentp -= i;
  1550. X            q = bufout + strlen(bufout);
  1551. X            p--;
  1552. X            break;
  1553. X        case '\f':
  1554. X            tabto = 0;                            /* optimizes */
  1555. X            *q = '\0';
  1556. X            if (instr)
  1557. X                (void) fprintf(outfile, "%s)%s\n", bufout, SHOW);
  1558. X            else
  1559. X                (void) fprintf(outfile, "%s\n", bufout);
  1560. X            endpage(outfile);
  1561. X            startpage(page_count + 1, outfile);
  1562. X            row = start_y;
  1563. X            (void) fprintf(outfile, "%d %d %s\n", start_x, row, MOVETO);
  1564. X            q = bufout;
  1565. X            currentp = 0;
  1566. X            instr = 0;
  1567. X            break;
  1568. X        case '\r':
  1569. X            tabto = 0;                            /* optimizes */
  1570. X            if (instr) {
  1571. X                *q = '\0';
  1572. X                (void) fprintf(outfile, "%s)%s\n", bufout, SHOW);
  1573. X                instr = 0;
  1574. X                q = bufout;
  1575. X            }
  1576. X            (void) fprintf(outfile, "%d %d %s\n", start_x, row, MOVETO);
  1577. X            currentp = 0;
  1578. X            break;
  1579. X        case '(':
  1580. X#ifdef KANJI
  1581. X            if (kflag && *(p+1) == 'J') {
  1582. X                kflag = 0;
  1583. X                p++;
  1584. X                break;
  1585. X            }
  1586. X#endif
  1587. X        case '\\':
  1588. X        case ')':
  1589. X            if (!instr) {
  1590. X                if (tabto) {
  1591. X                    (void) sprintf(q, "%d %s ", tabto, TAB);
  1592. X                    q += strlen(q);
  1593. X                    tabto = 0;
  1594. X                }
  1595. X                *q++ = '(';
  1596. X                instr = 1;
  1597. X            }
  1598. X            *q++ = '\\';
  1599. X            *q++ = *p;
  1600. X            currentp++;
  1601. X            break;
  1602. X#ifdef KANJI
  1603. X        case '\033':
  1604. X            if (*(p+1) == '$' && (*(p+2) == 'B' || *(p+2) == 'J')) {
  1605. X                if (!kfontopen) kfontopen = openkfont(KPLACE);
  1606. X                if (!kfontopen) fatal("No kanji font");
  1607. X                kflag = 1;
  1608. X                p++; p++;
  1609. X                *q = '\0';
  1610. X                if (instr)
  1611. X                    (void) fprintf(outfile, "%s)%s\n", bufout, SHOW);
  1612. X                else
  1613. X                    (void) fprintf(outfile, "%s\n", bufout);
  1614. X                q = bufout;
  1615. X                instr = 0;
  1616. X            }
  1617. X            else if (*(p+1) == '(' && (*(p+2) == 'B' || *(p+2) == 'J')) {
  1618. X                kflag = 0;
  1619. X                p++; p++;
  1620. X            }
  1621. X            break;
  1622. X        case '$':
  1623. X            if (!kflag && *(p+1) == '@') {
  1624. X                if (!kfontopen) kfontopen = openkfont(KPLACE);
  1625. X                if (!kfontopen) fatal("No kanji font");
  1626. X                kflag = 1;
  1627. X                p++;;
  1628. X                *q = '\0';
  1629. X                if (instr)
  1630. X                    (void) fprintf(outfile, "%s)%s\n", bufout, SHOW);
  1631. X                else
  1632. X                    (void) fprintf(outfile, "%s\n", bufout);
  1633. X                q = bufout;
  1634. X                instr = 0;
  1635. X                break;
  1636. X            }
  1637. X#endif
  1638. X        default:
  1639. X            /*
  1640. X             * According to the PostScript Language Manual, PostScript files
  1641. X             * can contain only "the printable subset of the ASCII character
  1642. X             * set (plus the newline marker)".
  1643. X             */
  1644. X            if (!isascii(*p) || !isprint(*p)) {
  1645. X                fatal("bad character in input");
  1646. X                /*NOTREACHED*/
  1647. X            }
  1648. X#ifdef KANJI
  1649. X            if (!instr && !kflag) {
  1650. X#else
  1651. X            if (!instr) {
  1652. X#endif
  1653. X                if (tabto) {
  1654. X                    (void) sprintf(q, "%d %s ", tabto, TAB);
  1655. X                    q += strlen(q);
  1656. X                    tabto = 0;
  1657. X                }
  1658. X                *q++ = '(';
  1659. X                instr = 1;
  1660. X            }
  1661. X#ifdef KANJI
  1662. X            if (kflag) {
  1663. X                if (*(p+1)) {
  1664. X                    (void) fprintf(outfile, "{<%s>} %s\n",
  1665. X                        kimage(*p, *(p+1)), SHOWK );
  1666. X                    p++;
  1667. X                    currentp++;
  1668. X                }
  1669. X            }
  1670. X            else {
  1671. X                *q++ = *p;
  1672. X                currentp++;
  1673. X            }
  1674. X#else
  1675. X            *q++ = *p;
  1676. X            currentp++;
  1677. X#endif
  1678. X            break;
  1679. X        }
  1680. X        if (q >= last) {
  1681. X            *q = '\0';
  1682. X            if (instr)
  1683. X                (void) fprintf(outfile, "%s)%s\n", bufout, SHOW);
  1684. X            else
  1685. X                (void) fprintf(outfile, "%s\n", bufout);
  1686. X            q = bufout;
  1687. X            instr = 0;
  1688. X        }
  1689. X    }
  1690. X    if (instr) {
  1691. X        (void) sprintf(q, ")%s", SHOW);
  1692. X        q += strlen(q);
  1693. X    }
  1694. X    else
  1695. X        *q = '\0';
  1696. X    if (q >= last) {
  1697. X        fatal("bufout overflow");
  1698. X        /*NOTREACHED*/
  1699. X    }
  1700. X    if (bufout[0] != '\0')
  1701. X        (void) fprintf(outfile, "%s\n", bufout);
  1702. X}
  1703. X
  1704. X/*
  1705. X * Find out who the user is, etc.
  1706. X * Possible system dependencies here...
  1707. X */
  1708. Xsetup()
  1709. X{
  1710. X    int len;
  1711. X    char *p;
  1712. X    long t, time();
  1713. X    int gethostname();
  1714. X    char *ctime(), *getlogin(), *malloc();
  1715. X    struct passwd *pw, *getpwuid();
  1716. X
  1717. X    if ((p = getlogin()) == (char *) NULL) {
  1718. X        if ((pw = getpwuid(getuid())) == (struct passwd *) NULL)
  1719. X            p = "Whoknows";
  1720. X        else
  1721. X            p = pw->pw_name;
  1722. X        endpwent();
  1723. X    }
  1724. X    username = (char *) malloc((unsigned) (strlen(p) + 1));
  1725. X    (void) strcpy(username, p);
  1726. X
  1727. X#ifdef HOSTNAME
  1728. X    (void) strncpy(hostname, HOSTNAME, sizeof(hostname));
  1729. X    hostname[sizeof(hostname) - 1] = '\0';
  1730. X#else
  1731. X    (void) gethostname(hostname, sizeof(hostname));
  1732. X#endif
  1733. X
  1734. X    t = time((long *) 0);
  1735. X    p = ctime(&t);
  1736. X    len = strlen(p);
  1737. X    *(p + len - 1) = '\0';        /* zap the newline character */
  1738. X    currentdate = (char *) malloc((unsigned) len);
  1739. X    (void) strcpy(currentdate, p);
  1740. X}
  1741. X
  1742. X/*
  1743. X * Print a header page
  1744. X * Assumes setup() has already been called to fill in the user, host, etc.
  1745. X * Uses HEADERFONT in HEADERPS point
  1746. X */
  1747. Xheader(nfiles, files)
  1748. Xint nfiles;
  1749. Xchar **files;
  1750. X{
  1751. X    register int i;
  1752. X    register char *p;
  1753. X
  1754. X    if (vflag) {
  1755. X        (void) fprintf(stderr, "printing header\n");
  1756. X        (void) fprintf(stderr, "%d file%s are:\n", nfiles,
  1757. X                            nfiles > 1 ? "s" : "");
  1758. X        if (nfiles == 0)
  1759. X            (void) fprintf(stderr, "\tstdin\n");
  1760. X        for (i = 0; i < nfiles; i++)
  1761. X            (void) fprintf(stderr, "\t%s\n", files[i]);
  1762. X    }
  1763. X
  1764. X    (void) fprintf(stdout, "%%%%Page: ? %d\n", ++page_count);
  1765. X    (void) fprintf(stdout, "%d /%s %s\n", HEADERPS, HEADERFONT, STARTHPAGE);
  1766. X
  1767. X    /*
  1768. X     * The header sheet looks like:
  1769. X     *
  1770. X     * ----------------------------
  1771. X     * ----------------------------
  1772. X     *
  1773. X     * User:
  1774. X     * Host:
  1775. X     * Date:
  1776. X     * Files:
  1777. X     *
  1778. X     * ----------------------------
  1779. X     * ----------------------------
  1780. X     */
  1781. X    row = START_Y_HEADER;
  1782. X    (void) printf("%s %d %d %s\n", NEWPATH, START_X, row, MOVETO);
  1783. X    (void) printf("%d %d %s\n", START_X + 400, row, LINETO);
  1784. X    row -= 6;
  1785. X    (void) printf("%d %d %s\n", START_X, row, MOVETO);
  1786. X    (void) printf("%d %d %s\n", START_X + 400, row, LINETO);
  1787. X    row -= 24;
  1788. X    (void) printf("%s\n", STROKE);
  1789. X
  1790. X    (void) printf("%d %d %s\n", START_X, row, MOVETO);
  1791. X    (void) sprintf(bufin, "User: %s", username);
  1792. X    proc(bufin, stdout);
  1793. X    row -= 24;
  1794. X    (void) printf("%d %d %s\n", START_X, row, MOVETO);
  1795. X    (void) sprintf(bufin, "Host: %s", hostname);
  1796. X    proc(bufin, stdout);
  1797. X    row -= 24;
  1798. X    (void) printf("%d %d %s\n", START_X, row, MOVETO);
  1799. X    (void) sprintf(bufin, "Date: %s", currentdate);
  1800. X    proc(bufin, stdout);
  1801. X    row -= 24;
  1802. X
  1803. X    if (nfiles == 0) {
  1804. X        (void) printf("%d %d %s\n", START_X, row, MOVETO);
  1805. X        (void) sprintf(bufin, "File: <stdin>");
  1806. X        proc(bufin, stdout);
  1807. X    }
  1808. X    else {
  1809. X        register int len, max, sum;
  1810. X
  1811. X        /*
  1812. X         * If the list of files is "too long" we'll only print as many as
  1813. X         * possible
  1814. X         * Arbitrary chop off point is 50 characters
  1815. X         * (assume bufin is bigger than this)
  1816. X         */
  1817. X        (void) printf("%d %d %s\n", START_X, row, MOVETO);
  1818. X        (void) sprintf(bufin, "File%s: ", nfiles > 1 ? "s" : "");
  1819. X        p = bufin + (sum = strlen(bufin));
  1820. X        max = 50;
  1821. X        for (i = 0; i < nfiles - 1; i++) {
  1822. X            sum += (len = strlen(files[i]) + 1);
  1823. X            if (sum >= max)
  1824. X                break;
  1825. X            (void) sprintf(p, "%s,", files[i]);
  1826. X            p += len;
  1827. X        }
  1828. X        sum += (len = strlen(files[i]) + 1);
  1829. X        if (sum < max)
  1830. X            (void) sprintf(p, "%s", files[i]);
  1831. X        else
  1832. X            (void) strcpy(p, "...");
  1833. X        proc(bufin, stdout);
  1834. X    }
  1835. X
  1836. X    row -= 12;
  1837. X    (void) printf("%s %d %d %s\n", NEWPATH, START_X, row, MOVETO);
  1838. X    (void) printf("%d %d %s\n", START_X + 400, row, LINETO);
  1839. X    row -= 6;
  1840. X    (void) printf("%d %d %s\n", START_X, row, MOVETO);
  1841. X    (void) printf("%d %d %s\n", START_X + 400, row, LINETO);
  1842. X    (void) printf("%s\n", STROKE);
  1843. X    (void) printf("1 %s\n", ENDPAGE);
  1844. X    if (fflush(stdout) == EOF) {
  1845. X        fatal("write error on stdout");
  1846. X        /*NOTREACHED*/
  1847. X    }
  1848. X}
  1849. X
  1850. X/*
  1851. X * Special version of fgets
  1852. X * Read until a formfeed, newline, or overflow
  1853. X * If a formfeed is the first character, return it immediately
  1854. X * If a formfeed is found after the first character, replace it by a newline
  1855. X * and push the formfeed back onto the input stream
  1856. X * A special case is a formfeed followed by a newline in which case the
  1857. X * newline is ignored 
  1858. X * The input buffer will be null-terminated and will *not* end with a newline
  1859. X * The buffer size n includes the null
  1860. X */
  1861. Xchar *
  1862. Xfgetline(s, n, iop)
  1863. Xchar *s;
  1864. Xint n;
  1865. Xregister FILE *iop;
  1866. X{
  1867. X    register int ch;
  1868. X    register char *cs;
  1869. X
  1870. X    if (n < 2) {
  1871. X        fatal("fgetline called with bad buffer size!?");
  1872. X        /*NOTREACHED*/
  1873. X    }
  1874. X
  1875. X    cs = s;
  1876. X    n--;                                /* the null */
  1877. X
  1878. X    /*
  1879. X     * Check out the special cases
  1880. X     */
  1881. X    if ((ch = getc(iop)) == EOF)
  1882. X        return((char *) NULL);
  1883. X    if (ch == '\f') {
  1884. X#ifdef PRBUG
  1885. X        if (pflag) {
  1886. X            /*
  1887. X             * Filter out the formfeeds
  1888. X             */
  1889. X            do {
  1890. X                if (ch == '\f')
  1891. X                    continue;
  1892. X                if (ch == '\n')
  1893. X                    break;
  1894. X                *cs++ = ch;
  1895. X                n--;
  1896. X            } while (n > 0 && (ch = getc(iop)) != EOF);
  1897. X            if (ch == EOF) {
  1898. X                if (ungetc(ch, iop) == EOF && !feof(iop)) {
  1899. X                    /* Shouldn't happen since a getc() was just done */
  1900. X                    fatal("fgetline - ungetc failed");
  1901. X                    /*NOTREACHED*/
  1902. X                }
  1903. X            }
  1904. X            else if (ch != '\n') {
  1905. X                fatal("fgetline - input line too long");
  1906. X                /*NOTREACHED*/
  1907. X            }
  1908. X            *cs = '\0';
  1909. X            return(s);
  1910. X        }
  1911. X#endif
  1912. X        if ((ch = getc(iop)) != '\n') {
  1913. X            /*
  1914. X             * If EOF was just read it will be noticed next time through
  1915. X             */
  1916. X            if (ungetc(ch, iop) == EOF && !feof(iop)) {
  1917. X                /* Shouldn't happen since a getc() was just done */
  1918. X                fatal("fgetline - ungetc failed");
  1919. X                /*NOTREACHED*/
  1920. X            }
  1921. X        }
  1922. X        *cs++ = '\f';
  1923. X        *cs = '\0';
  1924. X        return(s);
  1925. X    }
  1926. X
  1927. X    /*
  1928. X     * Check for "weird" input characters is made in proc()
  1929. X     */
  1930. X    while (n-- > 0) {
  1931. X        if (ch == '\f' || ch == '\n')
  1932. X            break;
  1933. X        *cs++ = ch;
  1934. X        if ((ch = getc(iop)) == EOF)
  1935. X            break;
  1936. X    }
  1937. X
  1938. X    if (ch == EOF && cs == s)        /* Nothing was read */
  1939. X        return((char *) NULL);
  1940. X    if (ch == '\f') {
  1941. X        if (ungetc(ch, iop) == EOF)
  1942. X            (void) fprintf(stderr, "fgetline - can't ungetc??\n");
  1943. X    }
  1944. X    else if (ch != '\n' && ch != EOF) {
  1945. X        fatal("fgetline - input line too long");
  1946. X        /*NOTREACHED*/
  1947. X    }
  1948. X    *cs = '\0';
  1949. X    return(s);
  1950. X}
  1951. X
  1952. X/*VARARGS*/
  1953. Xfatal(s, a, b, c, d, e, f, g, h, i, j)
  1954. Xchar *s;
  1955. X{
  1956. X
  1957. X    (void) fprintf(stderr, "%s: ", progname);
  1958. X    (void) fprintf(stderr, s, a, b, c, d, e, f, g, h, i, j);
  1959. X    (void) fprintf(stderr, "\n");
  1960. X    cleanup();
  1961. X    /*NOTREACHED*/
  1962. X}
  1963. X
  1964. X/*
  1965. X * Clean up and exit after an error
  1966. X */
  1967. Xcleanup()
  1968. X{
  1969. X#ifdef KANJI
  1970. X    if (kfontopen) closekfont();
  1971. X#endif
  1972. X    exit(1);
  1973. X}
  1974. X
  1975. END_OF_FILE
  1976. if test 29448 -ne `wc -c <'lwf.c'`; then
  1977.     echo shar: \"'lwf.c'\" unpacked with wrong size!
  1978. fi
  1979. # end of 'lwf.c'
  1980. fi
  1981. echo shar: End of archive 2 \(of 3\).
  1982. cp /dev/null ark2isdone
  1983. MISSING=""
  1984. for I in 1 2 3 ; do
  1985.     if test ! -f ark${I}isdone ; then
  1986.     MISSING="${MISSING} ${I}"
  1987.     fi
  1988. done
  1989. if test "${MISSING}" = "" ; then
  1990.     echo You have unpacked all 3 archives.
  1991.     rm -f ark[1-9]isdone
  1992. else
  1993.     echo You still need to unpack the following archives:
  1994.     echo "        " ${MISSING}
  1995. fi
  1996. ##  End of shell archive.
  1997. exit 0
  1998.  
  1999. -- 
  2000.          -- Greg, lee@uhccux.uhcc.hawaii.edu
  2001.